package com.yeskery.nut.http.sun;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.yeskery.nut.application.NutApplication;
import com.yeskery.nut.core.NutException;
import com.yeskery.nut.http.bio.BioResponse;
import com.yeskery.nut.util.IOUtils;
import com.yeskery.nut.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;

/**
 * JDK的Http 响应对象
 * @author sprout
 * 2022-05-19 11:28
 */
public class SunResponse extends BioResponse {

    /** 需要忽略的响应头 */
    private static final String[] EXCLUSIVE_HEADERS = {"Date", "Connection", "Content-Length"};

    /** Http 交换对象 */
    private final HttpExchange httpExchange;

    /** 输出流 */
    private final OutputStream outputStream;

    /**
     * 构建一个 {@link SunResponse} 对象
     * @param nutApplication Nut应用对象
     * @param outputStream 输出流对象
     * @param httpExchange Http 交换对象
     */
    public SunResponse(NutApplication nutApplication, OutputStream outputStream, HttpExchange httpExchange) {
        super(nutApplication, outputStream);
        this.outputStream = outputStream;
        this.httpExchange = httpExchange;
    }


    @Override
    protected void writeBytes(byte[] headers, byte[] bytes) {
        doWriteHeaderResponse(headers, bytes.length);
        IOUtils.writeByteArray(outputStream, bytes);
        output = true;
    }

    @Override
    protected void writeInputStream(byte[] headers, InputStream inputStream) {
        doWriteHeaderResponse(headers, 0L);
        IOUtils.transferInputStream(inputStream, outputStream);
        output = true;
    }

    /**
     * 输出响应头
     * @param headers 请求头数组
     * @param length 响应体长度
     */
    private void doWriteHeaderResponse(byte[] headers, long length) {
        String headerValue = new String(headers, StandardCharsets.UTF_8);
        String[] headerValues = headerValue.split("\r\n");
        int resultCode = Integer.parseInt(headerValues[0].split(" ")[1]);
        try {
            Headers responseHeaders = httpExchange.getResponseHeaders();
            for (int i = 1; i < headerValues.length; i++) {
                String header = headerValues[i];
                if (!StringUtils.isEmpty(header)) {
                    String[] splits = header.split(":");
                    if (splits.length == 2) {
                        if (Arrays.stream(EXCLUSIVE_HEADERS).noneMatch(x -> x.equals(splits[0]))) {
                            responseHeaders.put(splits[0], Collections.singletonList(splits[1]));
                        }
                    }
                }
            }
            httpExchange.sendResponseHeaders(resultCode, length);
        } catch (IOException e) {
            throw new NutException("Http Response Header Send Fail.", e);
        }
    }
}
